<?php
/* 
 * Copyright (c) 2018-2021   All rights reserved.
 * 
 * 创建时间：2021-06-04 17:19
 *
 * 项目：rm  -  $  - generateHelper.php
 *
 * 作者：liwei 
 */

namespace modules\levmodules\helpers;


use Lev;
use lev\base\Modelv;
use lev\base\Modulesv;
use lev\helpers\cacheFileHelpers;
use lev\helpers\ModulesHelper;
use lev\widgets\install\installWidget;

!defined('INLEV') && exit('Access Denied LEV');

class generateHelper
{

    public static $generateFiles, $tips = '';

    /**
     * 此处设置生成模块文件夹时需要替换掉的变量
     * @param $iden
     * @param array $replaceParam
     * @return array
     */
    public static function replaceVars($iden, $replaceParam = []) {
        $vars = [
            '{{Y}}'         => date('Y', Lev::$app['timestamp']),
            '{{$ymd}}'      => date('ymd', Lev::$app['timestamp']),
            '{{$Ymdx}}'     => date('Ymd', Lev::$app['timestamp']),
            '{{$YmdHi}}'    => date('Y-m-d H:i:s', Lev::$app['timestamp']),
            '\levccHelper'  => '\\'.$iden.'Helper',
            '\levcc'        => '\\'.Modulesv::getIdenNs($iden, $replaceParam['classdir']?:false),
            'levcc'         => $iden,
            '{{$classdir}}' => $replaceParam['classdir'], //父模块
            '{{$mudTitle}}' => $replaceParam['name'], //模块名称
            '{{$mudDescs}}' => $replaceParam['descs'], //模块描述
            '{{$version}}'  => $replaceParam['version'], //版本号
            '{{$navTitle}}' => $replaceParam['navTitle'] ?: Lev::cutString($replaceParam['name'], 8, ''), //版本号
        ];
        return $vars;
    }

    public static function createDzplugin($iden, $replaceParam, $unFiles = []) {

        if (empty($replaceParam['classdir'])) {
            $idenDir = '@modules/' . $iden;
            $generateDir = dirname(__DIR__) . '/_generates/_modules/_dzplugin/_levcc';
            $msg = static::creates($iden, $idenDir, $generateDir, $replaceParam, $unFiles, true);
        }else {
            $msg = Lev::responseMsg(-1, '子模块不支持创建DZ插件');
        }

        return $msg;
    }

    public static function createSubModule($iden, $replaceParam, $unFiles = []) {
        $idenDir = '@modules/' . $replaceParam['classdir'] . '/modules/' . $iden;
        $generateDir = dirname(__DIR__) . '/_generates/_modules/_submodule/_levcc';

        return static::creates($iden, $idenDir, $generateDir, $replaceParam, $unFiles);
    }

    public static function createModule($iden, $replaceParam, $unFiles = [])
    {
        if (empty($replaceParam['classdir'])) {
            $idenDir = '@modules/' . $iden;
            $generateDir = dirname(__DIR__) . '/_generates/_modules/_submodule/_levcc';
            $msg['_submodule'] = static::creates($iden, $idenDir, $generateDir, $replaceParam, $unFiles);
            if ($msg['_submodule']['status'] <0) {
                return $msg;
            }

            $generateDir = dirname(__DIR__) . '/_generates/_modules/_module/_levcc';
            $msg['_module'] = static::creates($iden, $idenDir, $generateDir, $replaceParam, $unFiles, true);
        }else {
            $msg = static::createSubModule($iden, $replaceParam, $unFiles);
        }

        return $msg;
    }

    public static function creates($iden, $idenDir, $generateDir, $replaceParam, $unFiles = [], $forceGen = false) {
        $arr = glob($generateDir . '/*');
        if (empty($arr)) {
            return Lev::responseMsg(-1, '无文件：'.$generateDir);
        }
        $moduleIdenDir = Lev::getAlias($idenDir);
        if (!$forceGen && is_dir($moduleIdenDir)) {
            return Lev::responseMsg(-2, '模块标识目录已存在：'.$iden);
        }
        if (installWidget::ckDzInstallFile($iden)) {
            $errMsg = 'Discuz！安装文件已经存在，如需重新生成请先删除:'.$iden.'/install.php、'.$iden.'/discuz_plugin_*.xml';
            Lev::setNotices($errMsg, true);
            return Lev::responseMsg(-3, $errMsg);
        }
        cacheFileHelpers::mkdirv($moduleIdenDir);
        $replaces = static::replaceVars($iden, $replaceParam);

        static::doGenerateFiles($generateDir, $moduleIdenDir, array_keys($replaces), array_values($replaces), $unFiles);
        return Lev::responseMsg(1, '', ['files'=>static::$generateFiles]);
    }

    public static function doGenerateFiles($sourceDir, $toDir, $search, $replace, $unFiles = []) {
        $files = glob(rtrim($sourceDir, '/') . '/*');
        foreach ($files as $src) {
            $name = str_replace($search, $replace, basename($src));
            $file = $toDir . '/'. $name;
            static::$generateFiles[] = $file;
            if (is_dir($src)) {
                cacheFileHelpers::mkdirv($file);
                self::doGenerateFiles($src, $file, $search, $replace, $unFiles);
            }else {
                (isset($unFiles[$file]) && is_file($file)) || //文件如果存在不覆盖，保留原文件
                file_put_contents($file, str_replace($search, $replace, file_get_contents($src)));
            }
        }
    }


    public static function isErrorIden($iden, $inputname = 'identifier') {
        if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]+$/', $iden)) {
            return Modelv::errorMsg($inputname, '只允许a-z、0-9和下划线，必须以字母、下划线开头', -2201);
        }
        return false;
    }
    public static function isExistIden($idenDir) {
        return is_dir(Lev::getAlias('@modules/'.$idenDir));
    }

    public static function varExportv($columns, $self = 0) {
        $self += 1;
        $enter = ",\n\n";
        $nbspx = "                ";
        $nbsp2 = "        ";
        if ($self > 1) {
            $enter = ",\n";
            for ($i=1; $i<$self; $i++) {
                $nbspx .= "    ";
                $nbsp2 .= "    ";
            }
        }

        foreach ($columns as $k => $v) $lens[] = strlen($k);
        $max = max($lens);

        $string = "array(\n";
        foreach ($columns as $k => $v) {
            cacheFileHelpers::isSerializeStr($v) && $v = unserialize($v);
            $len = $max - strlen($k);
            $nbsp = '';
            for ($i=0; $i<$len; $i++) $nbsp .= ' ';
            $string .= "$nbspx'$k'$nbsp => ".(is_array($v) ? static::varExportv($v, $self) : var_export($v, true)).$enter;
        }
        $string .= $nbsp2.')';
        return $string;
    }
}